/*
 * This implementation is based on the menu bar implementation in the book
 * "Murach's JavaScript and Dom Scripting" book, pages 580-587.
 */

var $ = function(id) {
    return document.getElementById(id);
}

var MenuBar = function (menuId) {
    this.menuBar = $(menuId);
    this.links =  this.menuBar.getElementsByTagName("a");

    for (var linkIndex = 0; linkIndex < this.links.length; linkIndex++) {
        var link = this.links[linkIndex];
        jsLib.event.add(link, "mouseover", this.highlight(link));
        jsLib.event.add(link, "mouseout", this.normal(link));

        // If a drop-down menu exists for the menu bar link...
        if (link.getAttribute("menu")) {
            // Store the menu in the array of drop-down menus
            var dropMenuName = link.getAttribute("menu");
            var dropMenu = $( dropMenuName );
            if ( dropMenu && dropMenu.tagName == "DIV" ) {
                var listItems = dropMenu.getElementsByTagName("li");

                // Remove the extra bottom border from the last menu item
                var last = listItems.length - 1;
                listItems[last].style.borderBottom = "none";

                // Add the event handlers to the items
                for (var itemIndex = 0; itemIndex < listItems.length; itemIndex++) {
                    var item = listItems[itemIndex];
                    jsLib.event.add( item, "mouseover", this.highlight(item));
                    jsLib.event.add( item, "mouseout", this.normal(item));
                }

                // Hide the drop-down menus and specify absolute positioning
                dropMenu.style.visibility = "hidden";
                dropMenu.style.position = "absolute";

                // Attach the event handlers that display the drop-down menu
                jsLib.event.add( link,      "mouseover",    this.displayMenu( dropMenu, link ));
                jsLib.event.add( dropMenu,  "mouseover",    this.displayMenu( dropMenu, link ));
                jsLib.event.add( link,      "mouseout",     this.hideMenuWithDelay());
                jsLib.event.add( dropMenu,  "mouseout",     this.hideMenuWithDelay());
            }
        } else {  // No drop-down menu exists for the menu bar link.
            jsLib.event.add( link, "mouseover", this.hideMenu() );
        }
    }
}

MenuBar.prototype.highlight = function(element){
    return function(){
        element.className = "highlight";
    }
}

MenuBar.prototype.normal = function(element){
    return function(){
        element.className = "";
    }
}

MenuBar.prototype.displayMenu = function(menu, link){
    var theMenuBar = this;
    return function(){
        // If a timer exists , clear it and delete the hideTimer property
        if (theMenuBar.hideTimer){
            clearTimeout(theMenuBar.hideTimer);
            delete theMenuBar.hideTimer;
        }

        // If a menu is visible , hide it
        if (theMenuBar.visibleMenu){
            theMenuBar.visibleMenu.style.visibility = "hidden";
            delete theMenuBar.visibleMenu;
        }

        var offsetTop, offsetLeft;
        offsetTop = jsLib.css.getOffsetTop(link);
        offsetTop += link.offsetHeight;
        offsetLeft = jsLib.css.getOffsetLeft(link);
        // TODO: revisit this.
        if(link.offsetParent.tagName != "BODY"){
            offsetTop += 1;
            offsetLeft += 2;
        }

        // Set the style object properties for the drop-down menu
        menu.style.top = offsetTop + "px";
        menu.style.left = offsetLeft + "px";

        // Store a reference to the drop-down menu and display it
        theMenuBar.visibleMenu = menu;
        menu.style.visibility = "visible";
    }
}

MenuBar.prototype.hideMenuWithDelay = function(){
    var theMenuBar = this;
    return function(){
        // Hide the menu after 750 milliseconds
        theMenuBar. hideTimer = setTimeout(theMenuBar.hideMenu(), 750);
    }
}

MenuBar.prototype.hideMenu = function(){
    var theMenuBar = this;
    return function(){
        // If a timer exists, clear it and delete the hideTimer property
        if (theMenuBar.hideTimer){
            clearTimeout(theMenuBar.hideTimer);
            delete theMenuBar.hideTimer;
        }
        // If a menu is visible , hide it
        if (theMenuBar.visibleMenu){
            theMenuBar.visibleMenu.style.visibility = "hidden";
            delete theMenuBar.visibleMenu;
        }
    }
}

var menuBar;

jsLib.dom.ready(function(){
    menuBar = new MenuBar("menubar");
})